#include <iostream>
#include <string>

// 代码的复用性

// 模版关键字
// typename:定义后面跟的字符串是数据类型
// T:参数化的数据类型变量名
// <>:参数名
template <typename T> // 模版函数
// 用法
T add(T a, T b)
{
    std::cout<<"模版函数"<<std::endl;
    return a + b;
}

int add(int a,int b) // 普通函数
{
    std::cout<<"普通函数"<<std::endl;
    return a + b;
}

// double add(double a,double b)
// {
//     return a + b;
// }
// std::string add(std::string a,std::string b)
// {
//     return a + b;
// }

int main()
{
    // // 显示调用模版函数
    // int a = add<int>(1, 2); // 用法：用int替换T
    // // 隐式调用:自动类型推导(根据传入的参数推导应该传入什么类型)
    // int b = add(1,2);
    // // double b = add<double>(3.1, 2.4);
    // std::cout << b << std::endl;

    // 当模版函数遇上普通函数:
    // int a = add(1,2);   // 如果类型匹配，优先调用普通函数(隐式调用时)
    // int a = add(1.2,2.1);  // 如果类型不匹配，优先模版函数 
    // 模版不支持类型的隐式转换
    // int a = add(1,'a');    // 调普通函数，如果没有普通函数，会报错
    int a = add<int>(1,'a');  // 显示调用，可以调用模版函数
    std::cout<<a<<std::endl;
    return 0;
}
